/*
 * RacesTable.java
 *
 * Created on November 6, 2007, 10:50 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package jia.editor.widgets;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.sql.SQLException;
import java.util.List;
import java.util.Vector;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import jia.editor.EditorMain;
import jia.editor.forms.RacesForm;
import jia.editor.lists.pnl_RacesList;
import jia.persist.Race;
import jia.tools.PanelSwapper;
import org.apache.log4j.Logger;


/**
 *
 * @author estell
 */
public class RacesTable extends JTable{
    JPopupMenu tblPop = new JPopupMenu();
    private static final Logger log = Logger.getLogger(RacesTable.class);
    pnl_RacesList raceList;
    public List dataList;
    racesTableModel mdl;
    
    /** Creates a new instance of RacesTable */
    public RacesTable(pnl_RacesList newRaceList) {
        super();
        //set a pointer to this tables parent JPanel
        this.raceList = newRaceList;
        try {
            
            //get the data for this table (to be used later)
            EditorMain.sqlMap.startTransaction();
            dataList = EditorMain.sqlMap.queryForList("getRaces");
            EditorMain.sqlMap.commitTransaction();
            
            log.error("Connection loaded!");
        } catch (SQLException ex) {
            log.error(ex);
            
        }finally{
            try {
                EditorMain.sqlMap.endTransaction();  
            } catch (SQLException ex) {
                ex.printStackTrace();
            }  
        }
        
        //set the table model for this table
        log.error("Setting the model");
        mdl = new racesTableModel();
        this.setModel(mdl);
        
        //set a few minor flags to prevent unexpected behavior
        log.error("Protecting the table");
        this.setCellSelectionEnabled(false);
        this.setRowSelectionAllowed(true);
        this.setColumnSelectionAllowed(false);
        this.setDragEnabled(false);
        this.getTableHeader().setReorderingAllowed(false);
        this.setShowGrid(true);
        this.setGridColor(Color.GRAY);
        
        //make sure only one row at a time can be selected
        log.error("setting selection model");
        this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        //add items to the tables pop-up menu
        log.error("Creating the menu");
        JMenuItem editMnuItem = new JMenuItem("Edit");
        editMnuItem.addActionListener(new EditRowsActionAdapter(this));
        editMnuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jia_ui/images/add.png")));
        tblPop.add(editMnuItem);
        
        JMenuItem deleteMnuItem = new JMenuItem("Delete");
        deleteMnuItem.addActionListener(new DeleteRowsActionAdapter(this));
        deleteMnuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jia_ui/images/delete.png")));
        tblPop.add(deleteMnuItem);
        
        //create and register this table's popup listener
        log.error("adding a mouse listener");
        MouseListener popupListener = new PopupListener(this);
        this.addMouseListener(popupListener);
        
    }
    
    //custom listener object for mouse actions
    class PopupListener extends MouseAdapter {
        RacesTable adaptee;
        
        PopupListener(RacesTable adaptee){
            this.adaptee = adaptee;
        }
        @Override
        public void mousePressed(MouseEvent e) {
            showPopup(e);
        }
        
        @Override
        public void mouseClicked(MouseEvent e){
            if (e.getClickCount() == 2){
                int rowIndex = adaptee.rowAtPoint(e.getPoint());
                raceList.setConsoleText("Double Clicked on row number: " + rowIndex);
            }
        }
        @Override
        public void mouseReleased(MouseEvent e) {
            showPopup(e);
        }
        private void showPopup(MouseEvent e) {
            if (e.isPopupTrigger()) {
                int rowIndex = adaptee.rowAtPoint(e.getPoint());
                adaptee.setRowSelectionInterval(rowIndex, rowIndex);
                tblPop.show(e.getComponent(), e.getX(), e.getY());
                
            }
        }
    }
    
    //special action for the pop up menu's Edit command
    class EditRowsActionAdapter implements ActionListener {
        RacesTable adaptee;
        
        EditRowsActionAdapter(RacesTable adaptee) {
            this.adaptee = adaptee;
        }
        public void actionPerformed(ActionEvent e) {
            Race thisRace = (Race)dataList.get(adaptee.getSelectedRow());
            //System.out.println("The following race ws chosen for edit: " + thisRace.getRACE_NAME() + ", " + thisRace.getRACE_ID());
            PanelSwapper.swap(new RacesForm(thisRace.getRACE_GUID()), raceList);
        }
    }
    
    //special action for the pop up menu's delete command
    class DeleteRowsActionAdapter implements ActionListener {
        RacesTable adaptee;
        
        DeleteRowsActionAdapter(RacesTable adaptee) {
            this.adaptee = adaptee;
        }
        
        public void actionPerformed(ActionEvent e) {
            raceList.setConsoleText("The following row was selected: " + adaptee.getValueAt(adaptee.getSelectedRow(), 0));
            
            int n = JOptionPane.showConfirmDialog(
                EditorMain.p_mainFrame,
                "Are you sure you want to delete this record?",
                "Warning!",
                JOptionPane.YES_NO_OPTION
                );
            raceList.setConsoleText(new Integer(n).toString());
            
            if (n == 0){//the answer was yes
                
                //TODO:  call the process that will remove this race
                int rowSelected = adaptee.getSelectedRow();
                Race thisRace = (Race)dataList.get(rowSelected);
                try {
                    
                    //get the data for this table (to be used later)
                    EditorMain.sqlMap.startTransaction();
                    int d = EditorMain.sqlMap.delete("deleteRace", thisRace);
                    
                    if (d == 1){
                        raceList.setConsoleText("The Record was deleted successfully");   
                        //TODO:  call process to delete the actual file as well.
                        EditorMain.sqlMap.commitTransaction();
                    }else{
                        raceList.setConsoleText("An error occured while attempting to delete the record."); 
                        
                    }
                } catch (SQLException ex) {
                    log.error(ex);
                }finally{
                    try {
                        EditorMain.sqlMap.endTransaction();
                    } catch (SQLException ex) {
                        ex.printStackTrace();
                    }
                }
                
                //adaptee.removeRowSelectionInterval(rowSelected, rowSelected);
                mdl.fireTableRowsDeleted(rowSelected, rowSelected);
                dataList.remove(rowSelected);

                //clean up the resource for this race.
                try{
                    // A File object to represent the filename
                    File f = new File("resources/res02/" + thisRace.getRACE_GUID() + ".xml");

                    // Make sure the file or directory exists and isn't write protected
                    if (!f.exists()){
                      throw new IllegalArgumentException(
                          "Delete: no such file or directory: " + thisRace.getRACE_GUID() + ".xml");
                    }

                    if (!f.canWrite()){
                      throw new IllegalArgumentException("Delete: write protected: " + thisRace.getRACE_GUID() + ".xml");
                    }

                    // If it is a directory, make sure it is empty
                    if (f.isDirectory()) {
                      String[] files = f.list();
                      if (files.length > 0){
                        throw new IllegalArgumentException("Delete: directory not empty: " + thisRace.getRACE_GUID() + ".xml");
                      }
                    }

                    // Attempt to delete it
                    boolean success = f.delete();

                    if (!success){
                      throw new IllegalArgumentException("Delete: deletion failed");
                    }
                }catch(Exception ef){

                }
                //adaptee.repaint();
            }else{
                //GNDN
            }
        }
    }
    
    //custom table model that handles the data
    class racesTableModel extends AbstractTableModel{
        
        private Vector<Object[]> dataRows;
        private boolean DEBUG = false;
        
        private String[] columnNames = {"Race Name", "Description", "Locked", "Enabled" };
        
        //make sure none of the columns are editable
        boolean[] canEdit = new boolean [] {
            false, false, false, false
        };
        
        //make sure none of the individual cells are editable
        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return canEdit [columnIndex];
        }
        
        //pulls the value of a cell
        public Object getValueAt(int row, int col) {
            Race thisRace = (Race)dataList.get(row);
            Object retVal = null;
            
            if(col == 0){
                retVal = thisRace.getRACE_NAME();
            }else if(col == 1){
                retVal = thisRace.getRACE_DESC();
            }else if(col == 2){
                if (thisRace.getISLOCKED() == 1){
                    retVal = new Boolean(true);
                }else{
                    retVal = new Boolean(false);
                }
                
            }else if(col == 3){
                if (thisRace.getISENABLED() == 1){
                    retVal = new Boolean(true);
                }else{
                    retVal = new Boolean(false);
                }
            }
            
            return retVal;
        }
        
        //returns the number of columns
        public int getColumnCount() {
            return columnNames.length;
        }
        
        //returns the number of rows
        public int getRowCount() {
            return dataList.size();
        }
        
        //gets the name of the column
        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }
        
        /*
         * JTable uses this method to determine the default renderer/ editor for
         * each cell. If we didn't implement this method, then the last column
         * would contain text ("true"/"false"), rather than a check box.
         */
        @Override
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }
        
        /*
         * Don't need to implement this method unless your table's data can
         * change.
         */
        @Override
        public void setValueAt(Object value, int row, int col) {
            if (DEBUG) {
                System.out.println("Setting value at " + row + "," + col
                    + " to " + value + " (an instance of "
                    + value.getClass() + ")");
            }
            
            //data[row][col] = value;
            dataList.set(row, value);
            fireTableCellUpdated(row, col);
            
            if (DEBUG) {
                System.out.println("New value of data:");
                printDebugData();
            }
        }
        
        private void printDebugData() {
            int numRows = getRowCount();
            int numCols = getColumnCount();
            
            for (int i = 0; i < numRows; i++) {
                System.out.print("    row " + i + ":");
                for (int j = 0; j < numCols; j++) {
                    //System.out.print("  " + data[i][j]);
                }
                System.out.println();
            }
            System.out.println("--------------------------");
        }
    }
}